#!/usr/bin/env python
# -*- coding=utf-8 -*-

# @File    :   test.py
# @Version :   1.0
# @Author  :   xin
# @Time    :   2023/10/23 15:18:19
# Description:
import os
import time
import platform
from HCNetSDK import *
# 设置SDK初始化依赖库路径


def SetSDKInitCfg():
    print("--------SetSDKInitCfg---------")
    global sdk
    # 设置HCNetSDKCom组件库和SSL库加载路径
    osLibPath = b"/home/aoting/testhivsion/test_hikvision/libs"
    sdk_ComPath = NET_DVR_LOCAL_SDK_PATH()
    sdk_ComPath.sPath = osLibPath
    os.chdir(osLibPath)
    sdk = cdll.LoadLibrary(b'./libhcnetsdk.so')
    sdk.NET_DVR_Init()
    # # 启用SDK写日志
    sdk.NET_DVR_SetLogToFile(3, bytes('./log', encoding='utf-8'), False)
    sdk.NET_DVR_SetSDKInitCfg(2, byref(sdk_ComPath))
    sdk.NET_DVR_SetSDKInitCfg(3,b'./libcrypto.so.1.1')
    sdk.NET_DVR_SetSDKInitCfg(4,b'./libssl.so.1.1')


picIndex =20

# 报警信息回调函数实现代码
def g_fMessageCallBack_Alarm(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser):
    print("------g_fMessageCallBack_Alarm---------")
     # 解析报警信息
    single_alrm = {}
    single_alrm['lCommand'] = hex(lCommand)

    picPath="/home/aoting/testhivsion/test_hikvision/pic"
    global picIndex
    picIndex=picIndex+1
    
    try:
        # ISAPI协议报警信息
        if lCommand == 0x6009:
            print('ISAPI协议报警信息上传')
            
        print("\n-----pAlarmer----------")
        print(pAlarmer)
        print(type(pAlarmer))
        print(dir(pAlarmer))
        Alarmer = pAlarmer.contents  # 取指针指向的结构体
        print("\n-----pAlarmer.contents----------")
        print(pAlarmer.contents)
        print(type(pAlarmer.contents))
        print(dir(pAlarmer.contents))
        if Alarmer.bySerialValid:
            deviceSeriel=""
            for n in Alarmer.sSerialNumber[0:48]:
                if n != 0:
                    deviceSeriel += chr(n)
            single_alrm['设备序列号:'] = deviceSeriel

        if Alarmer.byDeviceIPValid:
            deviceIP=""
            for n in Alarmer.sDeviceIP[0:128]:
                if n != 0:
                    deviceIP += chr(n)
            single_alrm['设备IP: '] = deviceIP

        if Alarmer.byUserIDValid:
            single_alrm['lUserID'] = Alarmer.lUserID
        print("\n----------pAlarmInfo-------------")
        print(pAlarmInfo)
        print(dir(pAlarmInfo))
        print("\n--------pAlarmInfo.contents---------")
        # print(pAlarmInfo.contents)
        # print(dir(pAlarmInfo.contents))
        # print(pAlarmInfo.contents.dwDeviceVersion)
        Alarm_struct = cast(pAlarmInfo, LPNET_DVR_ALARM_ISAPI_INFO).contents
        print(Alarm_struct)
        single_alrm['byDataType'] = Alarm_struct.byDataType
        single_alrm['byPicturesNumber'] = Alarm_struct.byPicturesNumber
        # # 报警信息XML或者JSON数据
        DataLen = Alarm_struct.dwAlarmDataLen
        print('DataLen {}'.format(DataLen))
        if DataLen != 0:
            buffInfo = string_at(Alarm_struct.pAlarmData, DataLen)
            print(buffInfo)
            with open('{}/IsapiInfo.txt'.format(picPath), 'wb') as fpInfo:
                fpInfo.write(buffInfo)

        # 报警信息图片数据
        nSize = 0
        pNum = Alarm_struct.byPicturesNumber
        print('pNum {}'.format(pNum))
        if pNum > 0:
            STRUCT = NET_DVR_ALARM_ISAPI_PICDATA * pNum
            PicStruct = cast(Alarm_struct.pPicPackData, POINTER(STRUCT)).contents
            print("\n---------PicStruct--------------")
            for nPicIndex in range(pNum):
                picType=PicStruct[nPicIndex].byPicType
                print("byPicType {}".format(picType))
                nSize = PicStruct[nPicIndex].dwPicLen
                print("nSize {}".format(nSize))
                
                if nSize != 0:
                    # strPicName = ''
                    # for n in PicStruct[nPicIndex].szFilename[0:256]:
                    #     if n != 0:
                    #         strPicName += chr(n)
                    # print("strPicName {} ".format(strPicName))
                    sFileName = ('{}/{}_ISAPI_Pic_{}.jpg' .format(picPath,picIndex,nPicIndex))
                    buffInfo = string_at(PicStruct[nPicIndex].pPicData, nSize)
                    end_index = buffInfo.find(b'\xff\xd9')
                    print("end_index {}".format(end_index))
                    result =buffInfo[:end_index+2] if end_index>0  else buffInfo
                    with open(sFileName, 'wb') as fpPic:
                        fpPic.write(result)
                        fpPic.write(b'\xff\xd9')
                        
    except Exception as err:
        print("------Exception---------")
        print(err)

    print("\n-------alarm_info----------")
    print(single_alrm)
    return



def loopWarn():
    print("--------loopWarn2---------")
    # 通用参数配置
    sdkCfg = NET_DVR_LOCAL_GENERAL_CFG()
    sdkCfg.byAlarmJsonPictureSeparate = 1
    sdk.NET_DVR_SetSDKLocalCfg(17, byref(sdkCfg))

    # 初始化用户id, 在调用正常是程序一般返回正数，故初始化一个负数
    UserID = c_long(-1)
    # 用户注册设备
    # c++传递进去的是byte型数据，需要转成byte型传进去，否则会乱码
    # 登录参数，包括设备地址、登录用户、密码等
    # struLoginInfo = NET_DVR_USER_LOGIN_INFO()
    # struLoginInfo.bUseAsynLogin = 0  # 同步登录方式
    # struLoginInfo.sDeviceAddress = bytes("192.168.0.220", "ascii")  # 设备IP地址
    # struLoginInfo.wPort = 8000  # 设备服务端口
    # struLoginInfo.sUserName = bytes("admin", "ascii")  # 设备登录用户名
    # struLoginInfo.sPassword = bytes("Aoting123", "ascii")  # 设备登录密码
    # struLoginInfo.byLoginMode = 0
    # struDeviceInfoV40 = NET_DVR_DEVICEINFO_V40()
    # sdk.NET_DVR_Login_V40.restype = c_long
    # sdk.NET_DVR_GetLastError.restype = c_uint
    # UserID = sdk.NET_DVR_Login_V40(byref(struLoginInfo), byref(struDeviceInfoV40))
    # if UserID < 0:
    #     print("Login failed, error code: %d" % sdk.NET_DVR_GetLastError())
    #     sdk.NET_DVR_Cleanup()
    # else:
    #     print('Login success：%s' % str(struDeviceInfoV40.struDeviceV30.sSerialNumber, encoding = "utf8"))

    
    
    
    #  启动报警监听并且设置回调函数接收事件
    handle = sdk.NET_DVR_StartListen_V30(bytes('192.168.0.230', 'ascii'),
                                         7200,
                                         MSGCallBack(g_fMessageCallBack_Alarm),
                                         None)
    if handle < 0:
        print("NET_DVR_StartListen_V30 failed, error code: %d" % sdk.NET_DVR_GetLastError())
        sdk.NET_DVR_Logout(UserID)
        sdk.NET_DVR_Cleanup()
    else:
        print('NET_DVR_StartListen_V30 成功')
    
    
    # 设置报警回调函数
    handle =sdk.NET_DVR_SetDVRMessageCallBack_V31(MSGCallBack(g_fMessageCallBack_Alarm), None)
    if handle < 0:
        print("NET_DVR_SetDVRMessageCallBack_V31 failed, error code: %d" % sdk.NET_DVR_GetLastError())
        sdk.NET_DVR_Logout(UserID)
        sdk.NET_DVR_Cleanup()
    else:
        print('NET_DVR_SetDVRMessageCallBack_V31 成功')
    
    while (True):
        pass
    
 


if __name__ == "__main__":
    print("-----main------")
    SetSDKInitCfg()
    loopWarn()
    pass
